import cv2
import numpy
import copy

#1. 在测试视频(OpenCV安装目录\sources\samples\data)上，使用基于混合高斯模型的背景提取算法，提取前景并显示(显示二值化图像，前景为白色)。

videoFileName = r'/Users/likai/Documents/AI 学习资料/OpenCV--图片库/data/vtest.avi'
#
# cap = cv2.VideoCapture(videoFileName)
# fgbg = cv2.createBackgroundSubtractorMOG2()
# thresh = 200
#
# while True:
#     ret, frame = cap.read()
#     if not ret:
#         break
#
#     fgmask = fgbg.apply(frame)
#     _, fgmask = cv2.threshold(fgmask, 30, 0xff, cv2.THRESH_BINARY)
#
#     bgImage = fgbg.getBackgroundImage()
#     _, cnts, _ = cv2.findContours(fgmask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#
#     count = 0
#     for c in cnts:
#         area = cv2.contourArea(c)
#         if area < thresh:
#             continue
#         count += 1
#         x, y, w, h = cv2.boundingRect(c)
#         cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0xff, 0), 2)
#     print('共检测到，', count, '个目标', '\n')
#     cv2.imshow('frame', frame)
#     cv2.imshow('bgImage', bgImage)
# cap.release()
# cv2.destroyAllWindows()


#2.在1基础上，将前景目标进行分割，进一步使用不同颜色矩形框标记，并在命令行窗口中输出每个矩形框的位置和大小。
#角点检测参数
feature_params = dict(maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7)
#llucasc kanade 光流法参数
lk_params = dict(winSize=(15, 15), maxLevel=2, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
cap = cv2.VideoCapture(videoFileName)

#计算第一帧特征点
ret, prev = cap.read()
prevGray = cv2.cvtColor(prev, cv2.COLOR_BGR2GRAY)
p0 = cv2.goodFeaturesToTrack(prevGray, **feature_params)


while True:
    ret, frame = cap.read()
    if not ret:
        break
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    #计算光流

    p1, st, err = cv2.calcOpticalFlowPyrLK(prevGray, gray, p0, None, **lk_params)
    # 选取好的跟踪点
    goodPoints = p1[st == 1]
    goodPrevPoints = p0[st == 1]

    #在结果图像中叠加画出特征点和计算出来的光流向量
    res = frame.copy()
    drawColor = (0, 0, 255)
    for i, (cur, prev) in enumerate(zip(goodPoints, goodPrevPoints)):
        x0, y0 = cur.ravel()
        x1, y1 = prev.ravel()
        cv2.line(res, (x0, y0), (x1, y1), drawColor)
        cv2.circle(res, (x0, y0), 3, drawColor)

    #更新上一帧
    prevGray = gray.copy()
    goodPoints.reshape(-1, 1, 2)

    #显示计算结果图像
    cv2.imshow('检测结果', res)
    #每一帧间隔30ms
    key = cv2.waitKey(30)

    if key == 27:
        break

cap.release()
cv2.destroyAllWindows()